(function(Raphael, SVG, $) {
  //绑定事件
  //显示拖拽调整大小框
  var showResize = function(i, r, p, currnet) {
    return function() {
      r.show();
      p.show();
      i.attr({
        width: currnet.width - 4,
        height: currnet.height - 4,
        x: currnet.x + 2,
        y: currnet.y + 2
      });
    };
  };

  //隐藏拖拽调整大小框
  var hideResize = function(i, r, p, currnet) {
    return function() {
      r.hide();
      p.hide();
      i.attr({
        width: currnet.width,
        height: currnet.height,
        x: currnet.x,
        y: currnet.y
      });
    };
  };

  //触发事件
  var callEvent = function(events, name, evt) {
    if (events[name] && typeof events[name] === "function") {
      events[name](evt);
    }
  };

  //拉斐尔JS相关操作
  //根据配置创建一块画布
  var createPaper = function(_paper) {
    var paper = null;
    if (_paper.el) {
      paper = new Raphael(_paper.el, _paper.width, _paper.height);
    } else {
      throw "无法创建画布";
    }
    return paper;
  };

  //加载SVG
  var loadSVG = function(_paper) {
    return SVG("#" + _paper.el + " svg");
  };

  //清空画布上的所有相关对象元素
  var clear = function(paper, svg) {
    if (paper) {
      paper.clear();
    }
    if (svg) {
      svg.clear();
    }
  };

  //画子对象集合
  var drawChildren = function(paper, current, context) {
    if (Array.isArray(current)) {
      for (var index = 0; index < current.length; index++) {
        draw(paper, current[index], context);
      }
    } else {
      draw(paper, current, context);
    }
  };

  //画集合
  var drawSet = function(paper, current, context) {
    if (!paper) {
      throw "必须创建一个先页面";
    }
    if (current.children) {
      drawChildren(paper, current.children, context);
    }
  };

  //画图片
  var drawImage = function(paper, current, context) {
    if (!paper) {
      throw "必须创建一个先页面";
    }
    //图片
    var i = paper.image(
      current.src,
      current.x,
      current.y,
      current.width,
      current.height
    );
    if (current.hidden) {
      i.hide();
    }

    //允许拖拽的情况下
    if (current.candrag) {
      //虚线框
      var r = paper.rect(current.x, current.y, current.width, current.height);
      r.attr("stroke-width", 2);
      r.attr("stroke-color", "black");
      r.attr("stroke-dasharray", ".");
      r.hide();
      //拖拽的点
      var p = paper.circle(
        current.x + current.width - 5,
        current.y + current.height - 5,
        10
      );
      p.attr("fill", "green");
      p.attr("stroke", "#fff");
      p.hide();

      //绑定事件
      i.hover(showResize(i, r, p, current), hideResize(i, r, p, current));
      p.hover(showResize(i, r, p, current), hideResize(i, r, p, current));

      //调整大小事件
      p.drag(
        function(dx, dy, x, y) {
          current.nw = current.width + dx;
          current.nh = current.height + dy;
          i.attr("width", current.nw);
          i.attr("height", current.nh);
          r.attr("width", current.nw);
          r.attr("height", current.nh);
          p.attr("cx", current.x + current.nw - 5);
          p.attr("cy", current.y + current.nh - 5);
        },
        function(x, y) {
          //触发事件
          console.log("start resizing");
        },
        function() {
          //触发事件
          if (current.nw) {
            current.width = current.nw;
            delete current.nw;
          }
          if (current.nh) {
            current.height = current.nh;
            delete current.nh;
          }

          console.log("end resizing");
          callEvent(context.events, "uiChange", context.ui);
        }
      );
      //移动事件
      i.drag(
        function(dx, dy, x, y) {
          var nx = current.x + dx;
          var ny = current.y + dy;
          i.attr("x", nx);
          i.attr("y", ny);
          r.attr("x", nx);
          r.attr("y", ny);
          p.attr("cx", nx + current.width);
          p.attr("cy", ny + current.height);
          current.nx = nx;
          current.ny = ny;
        },
        function(x, y) {
          //触发事件
          console.log("starting moving");
        },
        function() {
          //触发事件
          if (current.nx) {
            current.x = current.nx;
            delete current.nx;
          }
          if (current.ny) {
            current.y = current.ny;
            delete current.ny;
          }
          console.log("end moving");
          callEvent(context.events, "uiChange", context.ui);
        }
      );
    }
  };

  //画文本
  var drawText = function(paper, current, context) {
    if (!paper) {
      throw "必须创建一个先页面";
    }

    var svg = context.svg;
    var wrap = svg
      .foreignObject(current.width, current.height)
      .move(current.x, current.y);

    var color = current.color || "black";
    var size = current.size || 12;
    var txtHTML =
      '<div xmlns="http://www.w3.org/1999/xhtml" style="font-size:' +
      size +
      "px;color:" +
      color +
      ';word-break:break-all;">' +
      current.content +
      "</div>";
    var txtSVG = SVG(txtHTML);
    wrap.add(txtSVG);
    if (current.hidden) {
      wrap.hide();
    }

    //通过计算属性获得行高(动态行高法)
    var lineHeight = parseInt(
      window.getComputedStyle(wrap.node.querySelector("div")).lineHeight
    );

    if (current.inline) {
      if (current.height < lineHeight) {
        wrap.height(current.height);
      } else {
        wrap.height(lineHeight);
      }
    }

    //mask实现溢出效果
    // var mask = svg.mask().add(
    //   svg
    //     .rect(100, 100)
    //     .move(0, 0)
    //     .fill("#fff")
    // );
    // wrap.maskWith(mask);

    //是否启用拖拽
    if (current.candrag) {
      //弹性盒子
      //var box = wrap.bbox();
      //绘制矩形
      var rect = svg
        .rect(current.width, current.height)
        .move(current.x, current.y);
      rect.attr({
        fill: "#f06",
        "fill-opacity": 0,
        stroke: "#000",
        "stroke-dasharray": "2,2",
        "stroke-width": 1
      });
      rect.hide();
      //拖拽的点
      var p = svg
        .circle(20)
        .move(current.x + current.width - 14, current.y + current.height - 14);
      p.attr("fill", "green");
      p.attr("stroke", "#fff");
      p.hide();
      p.draggable()
        .on("dragmove", function(e) {
          var x = e.detail.box.x;
          var y = e.detail.box.y;
          var sx = rect.attr("x");
          var sy = rect.attr("y");
          var w = x - sx + 14;
          var h = y - sy + 14;

          if (w > 1) {
            rect.width(w);
            wrap.width(w);
          } else {
            rect.width(1);
            wrap.width(1);
          }
          if (h > 1) {
            if (current.inline) {
              rect.height(h);
              //设定高度
              if (h < lineHeight) {
                wrap.height(h);
              } else {
                wrap.height(lineHeight);
              }
            } else {
              rect.height(h);
              wrap.height(h);
            }
          } else {
            rect.height(1);
            wrap.height(1);
          }
        })
        .on("dragend", function(e) {
          var x = e.detail.box.x;
          var y = e.detail.box.y;
          var sx = rect.attr("x");
          var sy = rect.attr("y");
          var w = x - sx + 14;
          var h = y - sy + 14;
          if (w > 1) {
            current.width = w;
          } else {
            current.width = 1;
          }
          if (h > 1) {
            if (current.inline) {
              current.height = h;
            } else {
              current.height = h;
            }
          } else {
            current.height = 1;
          }
          callEvent(context.events, "uiChange", context.ui);
        });

      //调整顺序
      wrap.before(rect);
      //启用拖拽
      wrap
        .draggable()
        .on("dragmove", function(e) {
          var x = e.detail.box.x;
          var y = e.detail.box.y;
          rect.move(x, y);
          p.move(x + current.width - 14, y + current.height - 14);
        })
        .on("dragend", function(e) {
          //console.log(e);
          var nx = e.detail.box.x;
          var ny = e.detail.box.y;

          current.x = nx;
          current.y = ny;
          callEvent(context.events, "uiChange", context.ui);
        });

      //显示隐藏改变大小框
      wrap.mouseover(function() {
        rect.show();
        p.show();
      });
      wrap.mouseout(function() {
        rect.hide();
        p.hide();
      });
      rect.mouseover(function() {
        rect.show();
        p.show();
      });
      rect.mouseout(function() {
        rect.hide();
        p.hide();
      });
      p.mouseover(function() {
        rect.show();
        p.show();
      });
      p.mouseout(function() {
        // rect.hide();
        // p.hide();
      });
    }

    //console.log(box.width);
    //基本解决坐标不一致问题
    //var t = paper.rect(current.x, current.y, current.width, current.height);

    // t.attr({
    //   "font-size": 25 //字体大小
    //   //fill: "red" //字体颜色
    //   //"font-family": "宋体",
    //   //"font-weight": "bolder",
    //   //"text-anchor": "start" //更正坐标基线
    // });

    //遍历所有子元素
    // for (var index = 0; index < t.node.childNodes.length; index++) {
    //   (function(element) {
    //     if (element.tagName == "tspan") {
    //       element.setAttribute("dy", "1em");
    //       element.removeAttribute("dy");
    //     }
    //   })(t.node.childNodes[index]);
    // }

    //弹性盒子测试矩形
    //使用translate变幻更正坐标系统

    //t.translate(box.width / 2, box.height / 2);

    // var svg = context.svg;

    // //var rect = svg.rect(100, 100).attr({ fill: "#f06" });
    // var foreignObject = svg.foreignObject(current.width, current.height);
    // //foreignObject.translate(0, 0);
    // //words

    // foreignObject.draggable().on("beforedrag", function(e) {
    //   console.log(e);
    //   //e.preventDefault();
    //   // no other events are bound
    //   // drag was completely prevented
    // });

    // foreignObject.draggable().on("dragmove", function(e) {
    //   //e.preventDefault();
    //   console.log(e);
    //   e.detail.handler.move(100, 200);
    //   // events are still bound e.g. dragend will fire anyway
    // });
    // var text = svg
    //   .text("SVG.JS")
    //   .move(10, 10)
    //   .font({ size: 36 });

    // var txt = $(
    //   '<foreignObject x="0" y="100" width="120" height="50"><body ><p xmlns="http://www.w3.org/1999/xhtml">较长文文本一行放不下就换行</p></body></foreignObject>'
    // // );

    // if (current.candrag) {
    //   //显示拖拽调整大小框
    //   var showResizeT = function(t, r, p, currnet) {
    //     return function() {
    //       r.show();
    //       p.show();
    //       t.attr({
    //         width: currnet.width - 4,
    //         height: currnet.height - 4,
    //         x: currnet.x + 2,
    //         y: currnet.y + 2
    //       });
    //     };
    //   };

    //   //隐藏拖拽调整大小框
    //   var hideResizeT = function(t, r, p, currnet) {
    //     return function() {
    //       r.hide();
    //       p.hide();
    //       t.attr({
    //         width: currnet.width,
    //         height: currnet.height,
    //         x: currnet.x,
    //         y: currnet.y
    //       });
    //     };
    //   };

    //   //虚线框
    //   var r = paper.rect(box.x, box.y, current.width, current.height);
    //   r.attr("stroke-width", 2);
    //   r.attr("stroke-color", "black");
    //   r.attr("stroke-dasharray", ".");
    //   r.hide();
    //   //拖拽的点
    //   var p = paper.circle(
    //     current.x + current.width - 5,
    //     current.y + current.height - 5,
    //     10
    //   );
    //   p.attr("fill", "green");
    //   p.attr("stroke", "#fff");
    //   p.hide();

    //   //绑定事件
    //   t.hover(showResizeT(t, r, p, current), function() {});
    //   r.hover(showResizeT(t, r, p, current), function() {});
    //   p.hover(showResizeT(t, r, p, current), function() {});

    //   //移动字体事件
    //   t.drag(
    //     function(dx, dy, x, y) {
    //       var nx = current.x + dx;
    //       var ny = current.y + dy;
    //       t.attr("x", nx);
    //       t.attr("y", ny);
    //       r.attr("x", nx);
    //       r.attr("y", ny);
    //       p.attr("cx", nx + current.width);
    //       p.attr("cy", ny + current.height);
    //       current.nx = nx;
    //       current.ny = ny;
    //     },
    //     function(x, y) {
    //       //触发事件
    //       console.log("start moving");
    //     },
    //     function() {
    //       //触发事件
    //       if (current.nx) {
    //         current.x = current.nx;
    //         delete current.nx;
    //       }
    //       if (current.ny) {
    //         current.y = current.ny;
    //         delete current.ny;
    //       }
    //       console.log("end moving");
    //       callEvent(context.events, "uiChange", context.ui);
    //     }
    //   );

    //   //调整大小事件
    //   p.drag(
    //     function(dx, dy, x, y) {
    //       current.nw = current.width + dx;
    //       current.nh = current.height + dy;
    //       t.attr("width", current.nw);
    //       t.attr("height", current.nh);
    //       r.attr("width", current.nw);
    //       r.attr("height", current.nh);
    //       p.attr("cx", current.x + current.nw - 5);
    //       p.attr("cy", current.y + current.nh - 5);

    //       if (box.width > current.nw) {
    //         //alert("文字溢出");
    //       }
    //     },
    //     function(x, y) {
    //       //触发事件
    //       console.log("start resizing");
    //     },
    //     function() {
    //       //触发事件
    //       if (current.nw) {
    //         current.width = current.nw;
    //         delete current.nw;
    //       }
    //       if (current.nh) {
    //         current.height = current.nh;
    //         delete current.nh;
    //       }
    //       console.log("end resizing");
    //       callEvent(context.events, "uiChange", context.ui);
    //     }
    //   );
    // }
  };

  //画图
  var draw = function(paper, current, context) {
    switch (current.type) {
      case "set":
        drawSet(paper, current, context);
        break;
      case "image":
        drawImage(paper, current, context);
        break;
      case "text":
        drawText(paper, current, context);
      default:
        break;
    }
  };

  //显示
  var render = function(paper, context) {
    //ui存在则绘图
    if (context.ui) {
      draw(paper, context.ui, context);
    }
  };

  //设计器类
  var Design = function(id, options) {
    //赋值
    this.id = id;
    this.options = options;

    //内部变量
    var _paper = options.paper;
    var _ui = options.ui;
    //工具箱目前尚未支持
    //var _tools = options.tools;

    //创建的paper画布
    this.paper = createPaper(_paper);
    //读取已经创建paper对象的svg画布
    this.svg = loadSVG(_paper);

    //事件注册表
    this.events = {
      uiChange: options.uiChange
    };

    //显示方法
    //上下文
    this.context = {
      ui: _ui,
      svg: this.svg,
      events: this.events,
      self: this //调用对象的this指针
    };
    render(this.paper, this.context);
  };

  //主动刷新界面
  Design.prototype.refresh = function() {
    //清除已经存在的图像
    clear(this.paper, this.svg);
    //重新渲染
    render(this.paper, this.context);
  };
  //修改界面并重新渲染
  Design.prototype.setUI = function(ui) {
    //设置渲染的上下文ui对象并且重回
    this.context.ui = ui;
    this.refresh();
  };
  //获取ui
  Design.prototype.getUI = function() {
    return this.context.ui;
  };

  //重设画布的宽和高
  Design.prototype.setSize = function(w, h) {
    if (!this.paper) {
      throw "必须创建一个先页面";
    }
    this.paper.setSize(w, h);
  };

  //设置事件绑定(uiChange)
  Design.prototype.uiChange = function(handler) {
    this.events["uiChange"] = handler;
  };

  //导出设计器类export Desgin
  window.Design = Design;
})(Raphael, SVG, jQuery);
